<template>
  <div class="app-container">
    <el-row :gutter="10">

      <!--结构：左右结构，左侧：标签列表，右侧：选择宝贝-->
      <!--左侧本页面显示，右侧作为组件传值显示-->
      <!--标签列表-->
      <el-col :span="17">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>标签列表</span>
            <el-button
              :disabled="label_save_btn"
              style="float: right;"
              type="primary"
              size="mini"
              icon="el-icon-check"
              @click="save">保存</el-button>
          </div>
          <div>
            <!-- children:包含子节点字段，row-key：唯一标识 -->
            <!--default-expand-all：展开-->
            <!--highlight-current-row:选中某行样式-->
            <el-table
              :data="labelData"
              :tree-props="{ children: 'children' }"
              size="small"
              height="490"
              style="width: 100%;"
              row-key="id"
              highlight-current-row
              @row-click="thisLabelCommodity">
              <!-- 下钻的一级目录 -->
              <el-table-column label="标签名称">
                <template slot-scope="scope">
                  <el-input
                    v-model="scope.row.name"
                    clearable
                    placeholder="请输入"
                    style="width: 160px;"
                    class="filter-item"
                    size="small"
                    @change="inputChange(scope.row)" />
                </template>
              </el-table-column>
              <!-- 标签图片 -->
              <el-table-column label="标签图片" width="125px">
                <template slot-scope="scope">
                  <el-upload
                    :show-file-list="false"
                    :on-success="userImgSuccess"
                    :before-upload="beforeUserImgUpload"
                    :action="userHeadUploadApi"
                    class="avatar-uploader">
                    <div v-if="scope.row.url" style="display: flex;align-items: center;">
                      <img :src="scope.row.url" alt="点击打开" class="el-avatar" @click="viewImg(scope.row.url)" @click.stop>
                      <!--在此绑定click事件，先把需要上传替换值的信息给保存下来，为上传成功后的回显做准备-->
                      <div style="margin-left: 2px;margin-right: 2px;" @click="curRowInfo=scope.row">编辑</div>
                      <div @click="delImg(scope.row)">删除</div>
                    </div>
                    <!--在此绑定click事件，先把需要替换值的信息给保存下来，为上传成功后的回显做准备-->
                    <div v-else @click="curRowInfo=scope.row">添加图片</div>
                  </el-upload>
                </template>
              </el-table-column>
              <!-- 轮播图 -->
              <slide ref="slide" :cur-row-info="curRowInfo" @setCarouse = "setCarouse"/>
              <el-table-column label="移动" align="center" width="68px">
                <template slot-scope="scope">
                  <i class="el-icon-sort-down" style="font-size: 22px;" @click="bottomClick(scope.row)"/>
                  <i class="el-icon-sort-up" style="font-size: 22px;" @click="topClick(scope.row)"/>
                </template>
              </el-table-column>
              <el-table-column label="标签描述" width="210px">
                <template slot-scope="scope">
                  <el-input
                    v-model="scope.row.remark"
                    clearable
                    placeholder="请输入"
                    style="width: 160px;"
                    class="filter-item"
                    size="small"
                    @change="inputChange(scope.row)" />
                </template>
              </el-table-column>
              <el-table-column label="操作" align="center" width="65px">
                <template slot-scope="scope">
                  <!--删除触发事件-->
                  <el-popover
                    :ref="scope.row.id"
                    placement="top"
                    width="180">
                    <p>确定删除本条数据吗？</p>
                    <div style="text-align: right; margin: 0">
                      <el-button size="mini" @click="$refs[scope.row.id].doClose()">取消</el-button>
                      <el-button :loading="delLoading" type="primary" size="mini" @click="subDelete(scope.row)">确定</el-button>
                    </div>
                    <!--删除按钮-->
                    <el-button slot="reference" type="danger" icon="el-icon-delete" size="mini" />
                  </el-popover>
                </template>
              </el-table-column>
            </el-table>
            <!-- 图片放大预览功能 -->
            <imgMode ref="imgShow" />
          </div>
        </el-card>
      </el-col>
      <!-- 选择宝贝 -->
      <el-col :span="7">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <el-tooltip class="item" effect="dark" content="选择指定标签分配宝贝" placement="top">
              <span>宝贝列表</span>
            </el-tooltip>
            <el-button
              :disabled="addDisabled"
              icon="el-icon-plus"
              size="mini"
              style="float: right; margin-right: 10px"
              @click="add">添加</el-button>
            <el-button
              :disabled="addDisabled"
              icon="el-icon-check"
              size="mini"
              type="primary"
              style="float: right; margin-right: 10px"
              @click="doAddCommodity">保存</el-button>
          </div>
          <!--商品列表搜索商品输入框-->
          <el-input
            v-model="query.commodityName"
            suffix-icon="el-icon-search"
            clearable
            placeholder="请输入宝贝关键词"
            size="small"
            style="width: 200px;margin-bottom: 10px;"
            class="filter-item"
            @keyup.enter.native="commodityListSearch"/>
          <el-table
            ref="multipleTable"
            :data="data"
            :row-key="(row)=>{ return row.commodity_id}"
            height="400"
            size="small"
            tooltip-effect="dark"
            style="width: 100%"
            @selection-change="handleSelectionChange">
            <el-table-column
              :reserve-selection="true"
              type="selection"
              prop="commodity_id"
              width="55"/>
            <el-table-column prop="name" label="宝贝名称"/>
          </el-table>
          <!--分页组件-->
          <el-pagination
            :total="total"
            :current-page="page + 1"
            background
            style="margin-top: 8px;"
            layout="total, prev, pager, next, sizes"
            @size-change="sizeChange"
            @current-change="pageChange" />
        </el-card>
      </el-col>
    </el-row>
    <addCommodity ref="addCommodityMode" :label_id="label_id" @msgEvent="msgEvent"/>
  </div>
</template>

<script>
import initData from '@/mixins/initData'
import { getLabelList, saveLabelTable, saveLabelCheckPro } from '@/api/mall/label'
import { mapGetters } from 'vuex'
import imgMode from './imgMode'
import addCommodity from './addCommodity'
import slide from './slide'
/**
 * 注：
 * 1.要使用树形结构的表格，需要进行实体类拼装，且子节点名为children
 */
export default {
  components: { imgMode, addCommodity, slide },
  mixins: [initData],
  data() {
    return {
      query: {
        commodityName: ''
      },
      delLoading: false,
      labelData: [],
      curRowInfo: {},
      data: [],
      addDisabled: true,
      label_id: '',
      label_save_btn: false,
      labelIdArray: [],
      selectedData: [],
      sliderDialog: false
    }
  },
  computed: {
    ...mapGetters([
      'userHeadUploadApi'
    ])
  },
  created() {
    getLabelList().then(res => {
      this.labelData = res.content
      this.addData()
      console.log('this.labelData', this.labelData)
    })
  },
  methods: {
    // 获取商品的选中checkbox
    handleSelectionChange(rows) {
      this.selectedData = []
      if (rows) {
        rows.forEach(row => {
          if (row) {
            this.selectedData.push(row.commodity_id)
          }
        })
      }
    },
    // 保存选中宝贝
    doAddCommodity() {
      this.addDisabled = true
      const data = {
        label_id: this.label_id,
        commodity_id: this.selectedData
      }
      saveLabelCheckPro(data).then(res => {
        if (res.result) {
          this.$notify({
            title: res.msg,
            type: 'success',
            duration: 2500
          })
          // this.commodityListSearch()
        } else {
          this.$notify({
            title: res.msg,
            type: 'error',
            duration: 2500
          })
        }
        this.addDisabled = false
      })
    },
    save() {
      this.label_save_btn = true
      const labelTableData = this.labelData
      const param = { label_data: JSON.stringify(labelTableData), del_label_id: this.labelIdArray }
      saveLabelTable(param).then(res => {
        if (res.result) {
          getLabelList().then(r => {
            this.labelData = r.content
            this.addData()
          })
          this.$notify({
            title: res.msg,
            type: 'success',
            duration: 2500
          })
        } else {
          this.$notify({
            title: res.msg,
            type: 'error',
            duration: 2500
          })
        }
        this.label_save_btn = false
      })
    },
    addData() {
      const info = {
        id: this.uuid(),
        name: '',
        url: '',
        rotation_url: '',
        parent_id: '0',
        remark: ''
      }
      this.labelData.push(info)
    },
    recursionData() {
      this.labelData.map((item, i) => {
        // 最后一列添加一条空白数据
        if (item.parent_id === '0' && i === this.labelData.length - 1 && item.name.length > 0) {
          const info = {
            id: this.uuid(),
            name: '',
            url: '',
            rotation_url: '',
            parent_id: '0',
            remark: '',
            children: []
          }
          this.addChildren(info)
          this.labelData.push(info)
        } else {
          this.addChildren(item)
        }
      })
    },
    addChildren(item) {
      // 原始对象集
      const info = {
        id: this.uuid(),
        name: '',
        url: '',
        rotation_url: '',
        remark: '',
        parent_id: item.id
      }
      // 对象存在，为该对象添加一条空数据
      if (item['children'] && item['children'].length > 0) {
        const list = item['children']
        list.map((item, i) => {
          if (i === (list.length - 1) && item.name.length > 0) {
            list.push(info)
          }
        })
      } else {
        // 对象不存在则赋值一个数组，数组包含一条空数据
        item['children'].push(info)
      }
    },
    uuid() {
      const s = []
      const hexDigits = '0123456789abcdef'
      for (let i = 0; i < 36; i++) {
        s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
      }
      s[14] = '4'
      s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1)
      s[8] = s[13] = s[18] = s[23] = '-'
      return s.join('')
    },
    viewImg(url) {
      // 图片放大预览
      this.$refs.imgShow.dialog = true
      this.$refs.imgShow.imgUrl = url
    },
    delImg(info) {
      // 删除标签图片
      info.url = ''
    },
    delRotationUrl(info) {
      // 删除轮播图图片
      info.rotation_url = ''
      info.carouse_id = ''
    },
    inputChange() {
      // input输入后自动添加一条新的空白行
      this.recursionData()
    },
    topClick(row) {
      // 向上移动事件
      if (row.parent_id === '0') {
        const index = this.getIndex(row, this.labelData)
        // 一级目录移动、
        if (index !== 0) {
          this.labelData[index] = this.labelData.splice(index - 1, 1, this.labelData[index])[0]
        } else {
          this.$message({
            message: '已经是最顶端了，不能再移动了。。。',
            type: 'warning'
          })
        }
      } else {
        // 二级目录移动
        this.labelData.map((item) => {
          if (item.id === row.parent_id) {
            const index = this.getIndex(row, item.children)
            if (index !== 0) {
              item.children[index] = item.children.splice(index - 1, 1, item.children[index])[0]
            } else {
              this.$message({
                message: '已经是当前结构的最顶端了，不能再移动了。。。',
                type: 'warning'
              })
            }
          }
        })
      }
    },
    getIndex(info, list) {
      let num = 0
      // 获取当前list的位置
      list.map((item, i) => {
        if (item.id === info.id) {
          num = i
        }
      })
      return num
    },
    bottomClick(row) {
      // 向下移动事件
      if (row.parent_id === '0') {
        const index = this.getIndex(row, this.labelData)
        // 一级目录移动、
        if (index !== this.labelData.length - 1) {
          this.labelData[index] = this.labelData.splice(index + 1, 1, this.labelData[index])[0]
        } else {
          this.$message({
            message: '已经是最底端了，不能再移动了。。。',
            type: 'warning'
          })
        }
      } else {
        // 二级目录移动
        this.labelData.map((item) => {
          if (item.id === row.parent_id) {
            const index = this.getIndex(row, item.children)
            if (index !== item.children.length - 1) {
              item.children[index] = item.children.splice(index + 1, 1, item.children[index])[0]
            } else {
              this.$message({
                message: '已经是当前结构的最底端了，不能再移动了。。。',
                type: 'warning'
              })
            }
          }
        })
      }
    },
    subDelete(row) {
      // 删除整行数据
      if (row.parent_id === '0') {
        if (this.labelData.length === 1) {
          this.$message({
            message: '已经是最后一个一级标签了，不能再删除了。。。',
            type: 'warning'
          })
          return false
        }
        this.delLoading = true
        const index = this.getIndex(row, this.labelData)
        this.labelData.splice(index, 1)
        // 将当前行删除的一级标签id存到数组，点击保存时传递到后台进行逻辑删除
        this.labelIdArray.push(row.id)
      } else {
        this.labelData.map((item) => {
          if (item.id === row.parent_id) {
            if (item.children.length === 1) {
              this.$message({
                message: '已经是当前标签下最后一个二级标签了，不能再删除了。。。',
                type: 'warning'
              })
              return false
            }
            this.delLoading = true
            const index = this.getIndex(row, item.children)
            item.children.splice(index, 1)
          }
        })
      }
      this.delLoading = false
      this.$refs[row.id].doClose()
    },
    resetQuery() {
      this.$refs['query'].resetFields()
    },
    userImgSuccess(res) {
      // 数据回显至原表格，由于在点击之前已经把表格中该行的数据存于this.curRowInfo字段中，相当于把引用给了该字段
      // 所以改变this.curRowInfo中的值也就改变了表格中的值
      // 标签上传成功回显
      this.curRowInfo.url = res
    },
    rotationUrlSuccess(res) {
      // 轮播图上传成功后回显
      this.curRowInfo.rotation_url = res
    },
    beforeUserImgUpload(file) {
      const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' || file.type === 'image/jpg'
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isJPG) {
        this.$message.error('上传图片只能是 JPG、PNG、GIF、JPEG 格式!')
      }
      if (!isLt2M) {
        this.$message.error('上传图片大小不能超过 2MB!')
      }
      return isJPG && isLt2M
    },
    beforeInit() {
      this.url = 'api/card-commodity-list'
      const sort = 'create_date,desc'
      this.params = {
        page: this.page,
        size: this.size,
        sort: sort,
        label_brand_id: this.label_id,
        name: this.query.commodityName }
      return true
    },
    commodityListSearch() {
      this.data = []
      this.selectedData = []
      this.page = 0
      // 搜索商品列表
      this.init().then(() => {
        // 默认全选
        this.data.forEach(item => {
          this.$refs.multipleTable.toggleRowSelection(item, true)
        })
        // 添加按钮可点击
        this.addDisabled = false
      })
    },
    thisLabelCommodity(info) {
      // 获取商品中包含该标签的商品
      this.addDisabled = false
      this.label_id = info.id
      // 表格选中缓存清空
      this.$refs.multipleTable.clearSelection()
      // 搜索商品列表
      this.commodityListSearch()
    },
    add() {
      // 添加宝贝弹框
      this.$refs.addCommodityMode.dialog = true
      this.$refs.addCommodityMode.getList()
    },
    msgEvent(info) {
      // 商品弹框选择后的回调
      let result = true
      this.data.map(res => {
        if (res.commodity_id === info.commodity_id) {
          this.$message({
            message: '宝贝已存在，请选择其他宝贝',
            type: 'warning'
          })
          result = false
        }
      })
      // 商品列表不存在该值，则列表添加
      if (result) {
        this.data.push(info)
        this.$message({
          message: '选择成功',
          type: 'success'
        })
      }
    },
    selectCarouse(row) {
      this.curRowInfo = row
      this.$refs.slide.sliderDialog = true
    },
    setCarouse(carouse) {
      if (carouse && carouse.carouse_id) {
        this.$set(this.curRowInfo, 'rotation_url', carouse.image_url)
        this.$set(this.curRowInfo, 'carouse_id', carouse.carouse_id)
        this.$refs.slide.sliderDialog = false
      } else {
        this.$message({
          message: '请选择轮播图！',
          type: 'warning'
        })
      }
    }
  }
}
</script>
<style>
.clearfix:before,
  .clearfix:after {
    display: table;
    content: "";
  }
  .clearfix:after {
    clear: both
  }
</style>
